package com.mop.calc;
// $ANTLR 3.2 Sep 23, 2009 12:02:23 Calculator.g 2010-05-11 17:50:57

import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

import org.antlr.runtime.tree.*;

public class CalculatorParser extends Parser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "ID", "EQ", "SEMI", "ECHO", "STR", "LOOP", "LPAREN", "RPAREN", "ENDLP", "COMP", "NUM", "ADD", "MUL", "SUB", "DIV", "WS"
    };
    public static final int ENDLP=12;
    public static final int SUB=17;
    public static final int COMP=13;
    public static final int ID=4;
    public static final int EOF=-1;
    public static final int SEMI=6;
    public static final int MUL=16;
    public static final int LPAREN=10;
    public static final int NUM=14;
    public static final int STR=8;
    public static final int RPAREN=11;
    public static final int ECHO=7;
    public static final int WS=19;
    public static final int LOOP=9;
    public static final int EQ=5;
    public static final int DIV=18;
    public static final int ADD=15;

    // delegates
    // delegators


        public CalculatorParser(TokenStream input) {
            this(input, new RecognizerSharedState());
        }
        public CalculatorParser(TokenStream input, RecognizerSharedState state) {
            super(input, state);
            this.state.ruleMemo = new HashMap[22+1];
             
             
        }
        
    protected TreeAdaptor adaptor = new CommonTreeAdaptor();

    public void setTreeAdaptor(TreeAdaptor adaptor) {
        this.adaptor = adaptor;
    }
    public TreeAdaptor getTreeAdaptor() {
        return adaptor;
    }

    public String[] getTokenNames() { return CalculatorParser.tokenNames; }
    public String getGrammarFileName() { return "Calculator.g"; }


    public static class program_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "program"
    // Calculator.g:12:1: program : ( statement )+ -> ( statement )+ ;
    public final CalculatorParser.program_return program() throws RecognitionException {
        CalculatorParser.program_return retval = new CalculatorParser.program_return();
        retval.start = input.LT(1);
        int program_StartIndex = input.index();
        CommonTree root_0 = null;

        CalculatorParser.statement_return statement1 = null;


        RewriteRuleSubtreeStream stream_statement=new RewriteRuleSubtreeStream(adaptor,"rule statement");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 1) ) { return retval; }
            // Calculator.g:13:2: ( ( statement )+ -> ( statement )+ )
            // Calculator.g:13:4: ( statement )+
            {
            // Calculator.g:13:4: ( statement )+
            int cnt1=0;
            loop1:
            do {
                int alt1=2;
                int LA1_0 = input.LA(1);

                if ( (LA1_0==ID||LA1_0==ECHO||LA1_0==LOOP) ) {
                    alt1=1;
                }


                switch (alt1) {
            	case 1 :
            	    // Calculator.g:0:0: statement
            	    {
            	    pushFollow(FOLLOW_statement_in_program47);
            	    statement1=statement();

            	    state._fsp--;
            	    if (state.failed) return retval;
            	    if ( state.backtracking==0 ) stream_statement.add(statement1.getTree());

            	    }
            	    break;

            	default :
            	    if ( cnt1 >= 1 ) break loop1;
            	    if (state.backtracking>0) {state.failed=true; return retval;}
                        EarlyExitException eee =
                            new EarlyExitException(1, input);
                        throw eee;
                }
                cnt1++;
            } while (true);



            // AST REWRITE
            // elements: statement
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 14:2: -> ( statement )+
            {
                if ( !(stream_statement.hasNext()) ) {
                    throw new RewriteEarlyExitException();
                }
                while ( stream_statement.hasNext() ) {
                    adaptor.addChild(root_0, stream_statement.nextTree());

                }
                stream_statement.reset();

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 1, program_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "program"

    public static class statement_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "statement"
    // Calculator.g:17:1: statement : ( ID EQ atom_expr SEMI -> ^( EQ ID atom_expr ) | ECHO atom_expr SEMI -> ^( ECHO atom_expr ) | ECHO STR SEMI -> ^( ECHO STR ) | LOOP LPAREN ID EQ atom_expr SEMI comp_expr RPAREN ( statement )+ ENDLP SEMI -> ^( LOOP ID atom_expr comp_expr ( statement )+ ) );
    public final CalculatorParser.statement_return statement() throws RecognitionException {
        CalculatorParser.statement_return retval = new CalculatorParser.statement_return();
        retval.start = input.LT(1);
        int statement_StartIndex = input.index();
        CommonTree root_0 = null;

        Token ID2=null;
        Token EQ3=null;
        Token SEMI5=null;
        Token ECHO6=null;
        Token SEMI8=null;
        Token ECHO9=null;
        Token STR10=null;
        Token SEMI11=null;
        Token LOOP12=null;
        Token LPAREN13=null;
        Token ID14=null;
        Token EQ15=null;
        Token SEMI17=null;
        Token RPAREN19=null;
        Token ENDLP21=null;
        Token SEMI22=null;
        CalculatorParser.atom_expr_return atom_expr4 = null;

        CalculatorParser.atom_expr_return atom_expr7 = null;

        CalculatorParser.atom_expr_return atom_expr16 = null;

        CalculatorParser.comp_expr_return comp_expr18 = null;

        CalculatorParser.statement_return statement20 = null;


        CommonTree ID2_tree=null;
        CommonTree EQ3_tree=null;
        CommonTree SEMI5_tree=null;
        CommonTree ECHO6_tree=null;
        CommonTree SEMI8_tree=null;
        CommonTree ECHO9_tree=null;
        CommonTree STR10_tree=null;
        CommonTree SEMI11_tree=null;
        CommonTree LOOP12_tree=null;
        CommonTree LPAREN13_tree=null;
        CommonTree ID14_tree=null;
        CommonTree EQ15_tree=null;
        CommonTree SEMI17_tree=null;
        CommonTree RPAREN19_tree=null;
        CommonTree ENDLP21_tree=null;
        CommonTree SEMI22_tree=null;
        RewriteRuleTokenStream stream_ENDLP=new RewriteRuleTokenStream(adaptor,"token ENDLP");
        RewriteRuleTokenStream stream_STR=new RewriteRuleTokenStream(adaptor,"token STR");
        RewriteRuleTokenStream stream_RPAREN=new RewriteRuleTokenStream(adaptor,"token RPAREN");
        RewriteRuleTokenStream stream_ECHO=new RewriteRuleTokenStream(adaptor,"token ECHO");
        RewriteRuleTokenStream stream_EQ=new RewriteRuleTokenStream(adaptor,"token EQ");
        RewriteRuleTokenStream stream_ID=new RewriteRuleTokenStream(adaptor,"token ID");
        RewriteRuleTokenStream stream_SEMI=new RewriteRuleTokenStream(adaptor,"token SEMI");
        RewriteRuleTokenStream stream_LOOP=new RewriteRuleTokenStream(adaptor,"token LOOP");
        RewriteRuleTokenStream stream_LPAREN=new RewriteRuleTokenStream(adaptor,"token LPAREN");
        RewriteRuleSubtreeStream stream_statement=new RewriteRuleSubtreeStream(adaptor,"rule statement");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        RewriteRuleSubtreeStream stream_comp_expr=new RewriteRuleSubtreeStream(adaptor,"rule comp_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 2) ) { return retval; }
            // Calculator.g:18:2: ( ID EQ atom_expr SEMI -> ^( EQ ID atom_expr ) | ECHO atom_expr SEMI -> ^( ECHO atom_expr ) | ECHO STR SEMI -> ^( ECHO STR ) | LOOP LPAREN ID EQ atom_expr SEMI comp_expr RPAREN ( statement )+ ENDLP SEMI -> ^( LOOP ID atom_expr comp_expr ( statement )+ ) )
            int alt3=4;
            switch ( input.LA(1) ) {
            case ID:
                {
                alt3=1;
                }
                break;
            case ECHO:
                {
                int LA3_2 = input.LA(2);

                if ( (LA3_2==STR) ) {
                    alt3=3;
                }
                else if ( (LA3_2==ID||LA3_2==LPAREN||LA3_2==NUM) ) {
                    alt3=2;
                }
                else {
                    if (state.backtracking>0) {state.failed=true; return retval;}
                    NoViableAltException nvae =
                        new NoViableAltException("", 3, 2, input);

                    throw nvae;
                }
                }
                break;
            case LOOP:
                {
                alt3=4;
                }
                break;
            default:
                if (state.backtracking>0) {state.failed=true; return retval;}
                NoViableAltException nvae =
                    new NoViableAltException("", 3, 0, input);

                throw nvae;
            }

            switch (alt3) {
                case 1 :
                    // Calculator.g:18:4: ID EQ atom_expr SEMI
                    {
                    ID2=(Token)match(input,ID,FOLLOW_ID_in_statement68); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ID.add(ID2);

                    EQ3=(Token)match(input,EQ,FOLLOW_EQ_in_statement70); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_EQ.add(EQ3);

                    pushFollow(FOLLOW_atom_expr_in_statement72);
                    atom_expr4=atom_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr4.getTree());
                    SEMI5=(Token)match(input,SEMI,FOLLOW_SEMI_in_statement74); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_SEMI.add(SEMI5);



                    // AST REWRITE
                    // elements: ID, EQ, atom_expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 18:25: -> ^( EQ ID atom_expr )
                    {
                        // Calculator.g:18:28: ^( EQ ID atom_expr )
                        {
                        CommonTree root_1 = (CommonTree)adaptor.nil();
                        root_1 = (CommonTree)adaptor.becomeRoot(stream_EQ.nextNode(), root_1);

                        adaptor.addChild(root_1, stream_ID.nextNode());
                        adaptor.addChild(root_1, stream_atom_expr.nextTree());

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 2 :
                    // Calculator.g:19:4: ECHO atom_expr SEMI
                    {
                    ECHO6=(Token)match(input,ECHO,FOLLOW_ECHO_in_statement89); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ECHO.add(ECHO6);

                    pushFollow(FOLLOW_atom_expr_in_statement91);
                    atom_expr7=atom_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr7.getTree());
                    SEMI8=(Token)match(input,SEMI,FOLLOW_SEMI_in_statement93); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_SEMI.add(SEMI8);



                    // AST REWRITE
                    // elements: atom_expr, ECHO
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 19:24: -> ^( ECHO atom_expr )
                    {
                        // Calculator.g:19:26: ^( ECHO atom_expr )
                        {
                        CommonTree root_1 = (CommonTree)adaptor.nil();
                        root_1 = (CommonTree)adaptor.becomeRoot(stream_ECHO.nextNode(), root_1);

                        adaptor.addChild(root_1, stream_atom_expr.nextTree());

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 3 :
                    // Calculator.g:20:4: ECHO STR SEMI
                    {
                    ECHO9=(Token)match(input,ECHO,FOLLOW_ECHO_in_statement105); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ECHO.add(ECHO9);

                    STR10=(Token)match(input,STR,FOLLOW_STR_in_statement107); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_STR.add(STR10);

                    SEMI11=(Token)match(input,SEMI,FOLLOW_SEMI_in_statement109); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_SEMI.add(SEMI11);



                    // AST REWRITE
                    // elements: ECHO, STR
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 20:18: -> ^( ECHO STR )
                    {
                        // Calculator.g:20:20: ^( ECHO STR )
                        {
                        CommonTree root_1 = (CommonTree)adaptor.nil();
                        root_1 = (CommonTree)adaptor.becomeRoot(stream_ECHO.nextNode(), root_1);

                        adaptor.addChild(root_1, stream_STR.nextNode());

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 4 :
                    // Calculator.g:21:4: LOOP LPAREN ID EQ atom_expr SEMI comp_expr RPAREN ( statement )+ ENDLP SEMI
                    {
                    LOOP12=(Token)match(input,LOOP,FOLLOW_LOOP_in_statement122); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_LOOP.add(LOOP12);

                    LPAREN13=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_statement124); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_LPAREN.add(LPAREN13);

                    ID14=(Token)match(input,ID,FOLLOW_ID_in_statement126); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ID.add(ID14);

                    EQ15=(Token)match(input,EQ,FOLLOW_EQ_in_statement128); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_EQ.add(EQ15);

                    pushFollow(FOLLOW_atom_expr_in_statement130);
                    atom_expr16=atom_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr16.getTree());
                    SEMI17=(Token)match(input,SEMI,FOLLOW_SEMI_in_statement132); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_SEMI.add(SEMI17);

                    pushFollow(FOLLOW_comp_expr_in_statement134);
                    comp_expr18=comp_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_comp_expr.add(comp_expr18.getTree());
                    RPAREN19=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_statement136); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_RPAREN.add(RPAREN19);

                    // Calculator.g:21:54: ( statement )+
                    int cnt2=0;
                    loop2:
                    do {
                        int alt2=2;
                        int LA2_0 = input.LA(1);

                        if ( (LA2_0==ID||LA2_0==ECHO||LA2_0==LOOP) ) {
                            alt2=1;
                        }


                        switch (alt2) {
                    	case 1 :
                    	    // Calculator.g:0:0: statement
                    	    {
                    	    pushFollow(FOLLOW_statement_in_statement138);
                    	    statement20=statement();

                    	    state._fsp--;
                    	    if (state.failed) return retval;
                    	    if ( state.backtracking==0 ) stream_statement.add(statement20.getTree());

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt2 >= 1 ) break loop2;
                    	    if (state.backtracking>0) {state.failed=true; return retval;}
                                EarlyExitException eee =
                                    new EarlyExitException(2, input);
                                throw eee;
                        }
                        cnt2++;
                    } while (true);

                    ENDLP21=(Token)match(input,ENDLP,FOLLOW_ENDLP_in_statement141); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ENDLP.add(ENDLP21);

                    SEMI22=(Token)match(input,SEMI,FOLLOW_SEMI_in_statement143); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_SEMI.add(SEMI22);



                    // AST REWRITE
                    // elements: atom_expr, statement, ID, comp_expr, LOOP
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 21:76: -> ^( LOOP ID atom_expr comp_expr ( statement )+ )
                    {
                        // Calculator.g:21:78: ^( LOOP ID atom_expr comp_expr ( statement )+ )
                        {
                        CommonTree root_1 = (CommonTree)adaptor.nil();
                        root_1 = (CommonTree)adaptor.becomeRoot(stream_LOOP.nextNode(), root_1);

                        adaptor.addChild(root_1, stream_ID.nextNode());
                        adaptor.addChild(root_1, stream_atom_expr.nextTree());
                        adaptor.addChild(root_1, stream_comp_expr.nextTree());
                        if ( !(stream_statement.hasNext()) ) {
                            throw new RewriteEarlyExitException();
                        }
                        while ( stream_statement.hasNext() ) {
                            adaptor.addChild(root_1, stream_statement.nextTree());

                        }
                        stream_statement.reset();

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;}
                    }
                    break;

            }
            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 2, statement_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "statement"

    public static class comp_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "comp_expr"
    // Calculator.g:24:1: comp_expr : a= atom_expr COMP b= atom_expr -> ^( COMP $a $b) ;
    public final CalculatorParser.comp_expr_return comp_expr() throws RecognitionException {
        CalculatorParser.comp_expr_return retval = new CalculatorParser.comp_expr_return();
        retval.start = input.LT(1);
        int comp_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token COMP23=null;
        CalculatorParser.atom_expr_return a = null;

        CalculatorParser.atom_expr_return b = null;


        CommonTree COMP23_tree=null;
        RewriteRuleTokenStream stream_COMP=new RewriteRuleTokenStream(adaptor,"token COMP");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 3) ) { return retval; }
            // Calculator.g:25:2: (a= atom_expr COMP b= atom_expr -> ^( COMP $a $b) )
            // Calculator.g:25:4: a= atom_expr COMP b= atom_expr
            {
            pushFollow(FOLLOW_atom_expr_in_comp_expr170);
            a=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(a.getTree());
            COMP23=(Token)match(input,COMP,FOLLOW_COMP_in_comp_expr172); if (state.failed) return retval; 
            if ( state.backtracking==0 ) stream_COMP.add(COMP23);

            pushFollow(FOLLOW_atom_expr_in_comp_expr176);
            b=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(b.getTree());


            // AST REWRITE
            // elements: a, COMP, b
            // token labels: 
            // rule labels: retval, b, a
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);
            RewriteRuleSubtreeStream stream_b=new RewriteRuleSubtreeStream(adaptor,"rule b",b!=null?b.tree:null);
            RewriteRuleSubtreeStream stream_a=new RewriteRuleSubtreeStream(adaptor,"rule a",a!=null?a.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 26:2: -> ^( COMP $a $b)
            {
                // Calculator.g:26:5: ^( COMP $a $b)
                {
                CommonTree root_1 = (CommonTree)adaptor.nil();
                root_1 = (CommonTree)adaptor.becomeRoot(stream_COMP.nextNode(), root_1);

                adaptor.addChild(root_1, stream_a.nextTree());
                adaptor.addChild(root_1, stream_b.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 3, comp_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "comp_expr"

    public static class atom_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "atom_expr"
    // Calculator.g:29:1: atom_expr : ( LPAREN expr RPAREN -> expr | atom -> atom );
    public final CalculatorParser.atom_expr_return atom_expr() throws RecognitionException {
        CalculatorParser.atom_expr_return retval = new CalculatorParser.atom_expr_return();
        retval.start = input.LT(1);
        int atom_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token LPAREN24=null;
        Token RPAREN26=null;
        CalculatorParser.expr_return expr25 = null;

        CalculatorParser.atom_return atom27 = null;


        CommonTree LPAREN24_tree=null;
        CommonTree RPAREN26_tree=null;
        RewriteRuleTokenStream stream_RPAREN=new RewriteRuleTokenStream(adaptor,"token RPAREN");
        RewriteRuleTokenStream stream_LPAREN=new RewriteRuleTokenStream(adaptor,"token LPAREN");
        RewriteRuleSubtreeStream stream_atom=new RewriteRuleSubtreeStream(adaptor,"rule atom");
        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 4) ) { return retval; }
            // Calculator.g:30:2: ( LPAREN expr RPAREN -> expr | atom -> atom )
            int alt4=2;
            int LA4_0 = input.LA(1);

            if ( (LA4_0==LPAREN) ) {
                alt4=1;
            }
            else if ( (LA4_0==ID||LA4_0==NUM) ) {
                alt4=2;
            }
            else {
                if (state.backtracking>0) {state.failed=true; return retval;}
                NoViableAltException nvae =
                    new NoViableAltException("", 4, 0, input);

                throw nvae;
            }
            switch (alt4) {
                case 1 :
                    // Calculator.g:30:4: LPAREN expr RPAREN
                    {
                    LPAREN24=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_atom_expr203); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_LPAREN.add(LPAREN24);

                    pushFollow(FOLLOW_expr_in_atom_expr205);
                    expr25=expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_expr.add(expr25.getTree());
                    RPAREN26=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_atom_expr207); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_RPAREN.add(RPAREN26);



                    // AST REWRITE
                    // elements: expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 30:24: -> expr
                    {
                        adaptor.addChild(root_0, stream_expr.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 2 :
                    // Calculator.g:31:5: atom
                    {
                    pushFollow(FOLLOW_atom_in_atom_expr219);
                    atom27=atom();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_atom.add(atom27.getTree());


                    // AST REWRITE
                    // elements: atom
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 31:12: -> atom
                    {
                        adaptor.addChild(root_0, stream_atom.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;

            }
            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 4, atom_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "atom_expr"

    public static class atom_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "atom"
    // Calculator.g:34:1: atom : ( NUM -> NUM | ID -> ID );
    public final CalculatorParser.atom_return atom() throws RecognitionException {
        CalculatorParser.atom_return retval = new CalculatorParser.atom_return();
        retval.start = input.LT(1);
        int atom_StartIndex = input.index();
        CommonTree root_0 = null;

        Token NUM28=null;
        Token ID29=null;

        CommonTree NUM28_tree=null;
        CommonTree ID29_tree=null;
        RewriteRuleTokenStream stream_ID=new RewriteRuleTokenStream(adaptor,"token ID");
        RewriteRuleTokenStream stream_NUM=new RewriteRuleTokenStream(adaptor,"token NUM");

        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 5) ) { return retval; }
            // Calculator.g:35:2: ( NUM -> NUM | ID -> ID )
            int alt5=2;
            int LA5_0 = input.LA(1);

            if ( (LA5_0==NUM) ) {
                alt5=1;
            }
            else if ( (LA5_0==ID) ) {
                alt5=2;
            }
            else {
                if (state.backtracking>0) {state.failed=true; return retval;}
                NoViableAltException nvae =
                    new NoViableAltException("", 5, 0, input);

                throw nvae;
            }
            switch (alt5) {
                case 1 :
                    // Calculator.g:35:4: NUM
                    {
                    NUM28=(Token)match(input,NUM,FOLLOW_NUM_in_atom238); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_NUM.add(NUM28);



                    // AST REWRITE
                    // elements: NUM
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 35:8: -> NUM
                    {
                        adaptor.addChild(root_0, stream_NUM.nextNode());

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 2 :
                    // Calculator.g:36:4: ID
                    {
                    ID29=(Token)match(input,ID,FOLLOW_ID_in_atom247); if (state.failed) return retval; 
                    if ( state.backtracking==0 ) stream_ID.add(ID29);



                    // AST REWRITE
                    // elements: ID
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 36:7: -> ID
                    {
                        adaptor.addChild(root_0, stream_ID.nextNode());

                    }

                    retval.tree = root_0;}
                    }
                    break;

            }
            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 5, atom_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "atom"

    public static class expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "expr"
    // Calculator.g:39:1: expr : ( add_expr -> add_expr | mul_expr -> mul_expr | sub_expr -> sub_expr | div_expr -> div_expr );
    public final CalculatorParser.expr_return expr() throws RecognitionException {
        CalculatorParser.expr_return retval = new CalculatorParser.expr_return();
        retval.start = input.LT(1);
        int expr_StartIndex = input.index();
        CommonTree root_0 = null;

        CalculatorParser.add_expr_return add_expr30 = null;

        CalculatorParser.mul_expr_return mul_expr31 = null;

        CalculatorParser.sub_expr_return sub_expr32 = null;

        CalculatorParser.div_expr_return div_expr33 = null;


        RewriteRuleSubtreeStream stream_div_expr=new RewriteRuleSubtreeStream(adaptor,"rule div_expr");
        RewriteRuleSubtreeStream stream_mul_expr=new RewriteRuleSubtreeStream(adaptor,"rule mul_expr");
        RewriteRuleSubtreeStream stream_sub_expr=new RewriteRuleSubtreeStream(adaptor,"rule sub_expr");
        RewriteRuleSubtreeStream stream_add_expr=new RewriteRuleSubtreeStream(adaptor,"rule add_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 6) ) { return retval; }
            // Calculator.g:40:2: ( add_expr -> add_expr | mul_expr -> mul_expr | sub_expr -> sub_expr | div_expr -> div_expr )
            int alt6=4;
            switch ( input.LA(1) ) {
            case ADD:
                {
                alt6=1;
                }
                break;
            case MUL:
                {
                alt6=2;
                }
                break;
            case SUB:
                {
                alt6=3;
                }
                break;
            case DIV:
                {
                alt6=4;
                }
                break;
            default:
                if (state.backtracking>0) {state.failed=true; return retval;}
                NoViableAltException nvae =
                    new NoViableAltException("", 6, 0, input);

                throw nvae;
            }

            switch (alt6) {
                case 1 :
                    // Calculator.g:40:4: add_expr
                    {
                    pushFollow(FOLLOW_add_expr_in_expr265);
                    add_expr30=add_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_add_expr.add(add_expr30.getTree());


                    // AST REWRITE
                    // elements: add_expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 40:14: -> add_expr
                    {
                        adaptor.addChild(root_0, stream_add_expr.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 2 :
                    // Calculator.g:41:5: mul_expr
                    {
                    pushFollow(FOLLOW_mul_expr_in_expr276);
                    mul_expr31=mul_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_mul_expr.add(mul_expr31.getTree());


                    // AST REWRITE
                    // elements: mul_expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 41:15: -> mul_expr
                    {
                        adaptor.addChild(root_0, stream_mul_expr.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 3 :
                    // Calculator.g:42:5: sub_expr
                    {
                    pushFollow(FOLLOW_sub_expr_in_expr287);
                    sub_expr32=sub_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_sub_expr.add(sub_expr32.getTree());


                    // AST REWRITE
                    // elements: sub_expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 42:15: -> sub_expr
                    {
                        adaptor.addChild(root_0, stream_sub_expr.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;
                case 4 :
                    // Calculator.g:43:5: div_expr
                    {
                    pushFollow(FOLLOW_div_expr_in_expr299);
                    div_expr33=div_expr();

                    state._fsp--;
                    if (state.failed) return retval;
                    if ( state.backtracking==0 ) stream_div_expr.add(div_expr33.getTree());


                    // AST REWRITE
                    // elements: div_expr
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    if ( state.backtracking==0 ) {
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (CommonTree)adaptor.nil();
                    // 43:14: -> div_expr
                    {
                        adaptor.addChild(root_0, stream_div_expr.nextTree());

                    }

                    retval.tree = root_0;}
                    }
                    break;

            }
            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 6, expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "expr"

    public static class add_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "add_expr"
    // Calculator.g:46:1: add_expr : ADD ( atom_expr )+ -> ^( ADD ( atom_expr )+ ) ;
    public final CalculatorParser.add_expr_return add_expr() throws RecognitionException {
        CalculatorParser.add_expr_return retval = new CalculatorParser.add_expr_return();
        retval.start = input.LT(1);
        int add_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token ADD34=null;
        CalculatorParser.atom_expr_return atom_expr35 = null;


        CommonTree ADD34_tree=null;
        RewriteRuleTokenStream stream_ADD=new RewriteRuleTokenStream(adaptor,"token ADD");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 7) ) { return retval; }
            // Calculator.g:47:2: ( ADD ( atom_expr )+ -> ^( ADD ( atom_expr )+ ) )
            // Calculator.g:47:4: ADD ( atom_expr )+
            {
            ADD34=(Token)match(input,ADD,FOLLOW_ADD_in_add_expr315); if (state.failed) return retval; 
            if ( state.backtracking==0 ) stream_ADD.add(ADD34);

            // Calculator.g:47:8: ( atom_expr )+
            int cnt7=0;
            loop7:
            do {
                int alt7=2;
                int LA7_0 = input.LA(1);

                if ( (LA7_0==ID||LA7_0==LPAREN||LA7_0==NUM) ) {
                    alt7=1;
                }


                switch (alt7) {
            	case 1 :
            	    // Calculator.g:0:0: atom_expr
            	    {
            	    pushFollow(FOLLOW_atom_expr_in_add_expr317);
            	    atom_expr35=atom_expr();

            	    state._fsp--;
            	    if (state.failed) return retval;
            	    if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr35.getTree());

            	    }
            	    break;

            	default :
            	    if ( cnt7 >= 1 ) break loop7;
            	    if (state.backtracking>0) {state.failed=true; return retval;}
                        EarlyExitException eee =
                            new EarlyExitException(7, input);
                        throw eee;
                }
                cnt7++;
            } while (true);



            // AST REWRITE
            // elements: atom_expr, ADD
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 48:2: -> ^( ADD ( atom_expr )+ )
            {
                // Calculator.g:48:5: ^( ADD ( atom_expr )+ )
                {
                CommonTree root_1 = (CommonTree)adaptor.nil();
                root_1 = (CommonTree)adaptor.becomeRoot(stream_ADD.nextNode(), root_1);

                if ( !(stream_atom_expr.hasNext()) ) {
                    throw new RewriteEarlyExitException();
                }
                while ( stream_atom_expr.hasNext() ) {
                    adaptor.addChild(root_1, stream_atom_expr.nextTree());

                }
                stream_atom_expr.reset();

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 7, add_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "add_expr"

    public static class mul_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "mul_expr"
    // Calculator.g:51:1: mul_expr : MUL ( atom_expr )+ -> ^( MUL ( atom_expr )+ ) ;
    public final CalculatorParser.mul_expr_return mul_expr() throws RecognitionException {
        CalculatorParser.mul_expr_return retval = new CalculatorParser.mul_expr_return();
        retval.start = input.LT(1);
        int mul_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token MUL36=null;
        CalculatorParser.atom_expr_return atom_expr37 = null;


        CommonTree MUL36_tree=null;
        RewriteRuleTokenStream stream_MUL=new RewriteRuleTokenStream(adaptor,"token MUL");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 8) ) { return retval; }
            // Calculator.g:52:2: ( MUL ( atom_expr )+ -> ^( MUL ( atom_expr )+ ) )
            // Calculator.g:52:4: MUL ( atom_expr )+
            {
            MUL36=(Token)match(input,MUL,FOLLOW_MUL_in_mul_expr341); if (state.failed) return retval; 
            if ( state.backtracking==0 ) stream_MUL.add(MUL36);

            // Calculator.g:52:8: ( atom_expr )+
            int cnt8=0;
            loop8:
            do {
                int alt8=2;
                int LA8_0 = input.LA(1);

                if ( (LA8_0==ID||LA8_0==LPAREN||LA8_0==NUM) ) {
                    alt8=1;
                }


                switch (alt8) {
            	case 1 :
            	    // Calculator.g:0:0: atom_expr
            	    {
            	    pushFollow(FOLLOW_atom_expr_in_mul_expr343);
            	    atom_expr37=atom_expr();

            	    state._fsp--;
            	    if (state.failed) return retval;
            	    if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr37.getTree());

            	    }
            	    break;

            	default :
            	    if ( cnt8 >= 1 ) break loop8;
            	    if (state.backtracking>0) {state.failed=true; return retval;}
                        EarlyExitException eee =
                            new EarlyExitException(8, input);
                        throw eee;
                }
                cnt8++;
            } while (true);



            // AST REWRITE
            // elements: MUL, atom_expr
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 53:2: -> ^( MUL ( atom_expr )+ )
            {
                // Calculator.g:53:5: ^( MUL ( atom_expr )+ )
                {
                CommonTree root_1 = (CommonTree)adaptor.nil();
                root_1 = (CommonTree)adaptor.becomeRoot(stream_MUL.nextNode(), root_1);

                if ( !(stream_atom_expr.hasNext()) ) {
                    throw new RewriteEarlyExitException();
                }
                while ( stream_atom_expr.hasNext() ) {
                    adaptor.addChild(root_1, stream_atom_expr.nextTree());

                }
                stream_atom_expr.reset();

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 8, mul_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "mul_expr"

    public static class sub_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "sub_expr"
    // Calculator.g:56:1: sub_expr : SUB atom_expr atom_expr -> ^( SUB atom_expr atom_expr ) ;
    public final CalculatorParser.sub_expr_return sub_expr() throws RecognitionException {
        CalculatorParser.sub_expr_return retval = new CalculatorParser.sub_expr_return();
        retval.start = input.LT(1);
        int sub_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token SUB38=null;
        CalculatorParser.atom_expr_return atom_expr39 = null;

        CalculatorParser.atom_expr_return atom_expr40 = null;


        CommonTree SUB38_tree=null;
        RewriteRuleTokenStream stream_SUB=new RewriteRuleTokenStream(adaptor,"token SUB");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 9) ) { return retval; }
            // Calculator.g:57:2: ( SUB atom_expr atom_expr -> ^( SUB atom_expr atom_expr ) )
            // Calculator.g:57:4: SUB atom_expr atom_expr
            {
            SUB38=(Token)match(input,SUB,FOLLOW_SUB_in_sub_expr367); if (state.failed) return retval; 
            if ( state.backtracking==0 ) stream_SUB.add(SUB38);

            pushFollow(FOLLOW_atom_expr_in_sub_expr369);
            atom_expr39=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr39.getTree());
            pushFollow(FOLLOW_atom_expr_in_sub_expr371);
            atom_expr40=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr40.getTree());


            // AST REWRITE
            // elements: atom_expr, atom_expr, SUB
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 58:2: -> ^( SUB atom_expr atom_expr )
            {
                // Calculator.g:58:5: ^( SUB atom_expr atom_expr )
                {
                CommonTree root_1 = (CommonTree)adaptor.nil();
                root_1 = (CommonTree)adaptor.becomeRoot(stream_SUB.nextNode(), root_1);

                adaptor.addChild(root_1, stream_atom_expr.nextTree());
                adaptor.addChild(root_1, stream_atom_expr.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 9, sub_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "sub_expr"

    public static class div_expr_return extends ParserRuleReturnScope {
        CommonTree tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "div_expr"
    // Calculator.g:61:1: div_expr : DIV atom_expr atom_expr -> ^( DIV atom_expr atom_expr ) ;
    public final CalculatorParser.div_expr_return div_expr() throws RecognitionException {
        CalculatorParser.div_expr_return retval = new CalculatorParser.div_expr_return();
        retval.start = input.LT(1);
        int div_expr_StartIndex = input.index();
        CommonTree root_0 = null;

        Token DIV41=null;
        CalculatorParser.atom_expr_return atom_expr42 = null;

        CalculatorParser.atom_expr_return atom_expr43 = null;


        CommonTree DIV41_tree=null;
        RewriteRuleTokenStream stream_DIV=new RewriteRuleTokenStream(adaptor,"token DIV");
        RewriteRuleSubtreeStream stream_atom_expr=new RewriteRuleSubtreeStream(adaptor,"rule atom_expr");
        try {
            if ( state.backtracking>0 && alreadyParsedRule(input, 10) ) { return retval; }
            // Calculator.g:62:2: ( DIV atom_expr atom_expr -> ^( DIV atom_expr atom_expr ) )
            // Calculator.g:62:4: DIV atom_expr atom_expr
            {
            DIV41=(Token)match(input,DIV,FOLLOW_DIV_in_div_expr395); if (state.failed) return retval; 
            if ( state.backtracking==0 ) stream_DIV.add(DIV41);

            pushFollow(FOLLOW_atom_expr_in_div_expr397);
            atom_expr42=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr42.getTree());
            pushFollow(FOLLOW_atom_expr_in_div_expr399);
            atom_expr43=atom_expr();

            state._fsp--;
            if (state.failed) return retval;
            if ( state.backtracking==0 ) stream_atom_expr.add(atom_expr43.getTree());


            // AST REWRITE
            // elements: atom_expr, DIV, atom_expr
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            if ( state.backtracking==0 ) {
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (CommonTree)adaptor.nil();
            // 63:2: -> ^( DIV atom_expr atom_expr )
            {
                // Calculator.g:63:5: ^( DIV atom_expr atom_expr )
                {
                CommonTree root_1 = (CommonTree)adaptor.nil();
                root_1 = (CommonTree)adaptor.becomeRoot(stream_DIV.nextNode(), root_1);

                adaptor.addChild(root_1, stream_atom_expr.nextTree());
                adaptor.addChild(root_1, stream_atom_expr.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;}
            }

            retval.stop = input.LT(-1);

            if ( state.backtracking==0 ) {

            retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
            if ( state.backtracking>0 ) { memoize(input, 10, div_expr_StartIndex); }
        }
        return retval;
    }
    // $ANTLR end "div_expr"

    // Delegated rules


 

    public static final BitSet FOLLOW_statement_in_program47 = new BitSet(new long[]{0x0000000000000292L});
    public static final BitSet FOLLOW_ID_in_statement68 = new BitSet(new long[]{0x0000000000000020L});
    public static final BitSet FOLLOW_EQ_in_statement70 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_statement72 = new BitSet(new long[]{0x0000000000000040L});
    public static final BitSet FOLLOW_SEMI_in_statement74 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ECHO_in_statement89 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_statement91 = new BitSet(new long[]{0x0000000000000040L});
    public static final BitSet FOLLOW_SEMI_in_statement93 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ECHO_in_statement105 = new BitSet(new long[]{0x0000000000000100L});
    public static final BitSet FOLLOW_STR_in_statement107 = new BitSet(new long[]{0x0000000000000040L});
    public static final BitSet FOLLOW_SEMI_in_statement109 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LOOP_in_statement122 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_statement124 = new BitSet(new long[]{0x0000000000000010L});
    public static final BitSet FOLLOW_ID_in_statement126 = new BitSet(new long[]{0x0000000000000020L});
    public static final BitSet FOLLOW_EQ_in_statement128 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_statement130 = new BitSet(new long[]{0x0000000000000040L});
    public static final BitSet FOLLOW_SEMI_in_statement132 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_comp_expr_in_statement134 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_statement136 = new BitSet(new long[]{0x0000000000001290L});
    public static final BitSet FOLLOW_statement_in_statement138 = new BitSet(new long[]{0x0000000000001290L});
    public static final BitSet FOLLOW_ENDLP_in_statement141 = new BitSet(new long[]{0x0000000000000040L});
    public static final BitSet FOLLOW_SEMI_in_statement143 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_atom_expr_in_comp_expr170 = new BitSet(new long[]{0x0000000000002000L});
    public static final BitSet FOLLOW_COMP_in_comp_expr172 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_comp_expr176 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LPAREN_in_atom_expr203 = new BitSet(new long[]{0x0000000000078000L});
    public static final BitSet FOLLOW_expr_in_atom_expr205 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_atom_expr207 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_atom_in_atom_expr219 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_NUM_in_atom238 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ID_in_atom247 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_add_expr_in_expr265 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_mul_expr_in_expr276 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_sub_expr_in_expr287 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_div_expr_in_expr299 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ADD_in_add_expr315 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_add_expr317 = new BitSet(new long[]{0x0000000000004412L});
    public static final BitSet FOLLOW_MUL_in_mul_expr341 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_mul_expr343 = new BitSet(new long[]{0x0000000000004412L});
    public static final BitSet FOLLOW_SUB_in_sub_expr367 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_sub_expr369 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_sub_expr371 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_DIV_in_div_expr395 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_div_expr397 = new BitSet(new long[]{0x0000000000004410L});
    public static final BitSet FOLLOW_atom_expr_in_div_expr399 = new BitSet(new long[]{0x0000000000000002L});

}